<html><head>

<script type="text/javascript" src="http://api.msappspace.com/JSLoader/JSLoader.aspx?v=0.7&f=rpc"></script>	
<script type="text/javascript">

/**
 * Tic-Tac-Toe static object controller namespace
 */
var TTT = {
   Keys: {
       NAME: "name",
       SCORE: "score"
   },
   RequestKeys: {
       VIEWERDATA: "viewer_data",
       VIEWER: "v",
       VIEWER_FRIENDS: "vf",
       VIEWER_PHOTOS: "vp"
   },
   Players: {
       Computer: "O",
       Human: "X"
   },
   /**
    * Actual Tic-Tac-Toe game engine.
    */
   Game: function(){

      var me = this;
      var cellbackEmpty = "#555";
      var cellbackWin = "#88E";
      var cellbackCustomBG = "";
      
      this.customBG = new TTT.CustomBackground();

      /**
       * Clear the game and reset
       */
      this.clear = function(){
         var i;
         for(i = 0; i < this.gameCells.length; i++){
            this.gameCells[i].innerHTML = "";

            if(this.customBG.usingCustomBG()){
               this.gameCells[i].style.backgroundColor = this.customBG.cellbackCustomBG;
            }
            else{
               this.gameCells[i].style.backgroundColor = cellbackEmpty;
            }
         }
         this.moves = new Array(9);
         this.hasWinner = false;
         this.winningCells = null;
         this.currentPlayer = TTT.Players.Human;
      }

      /**
       * Colors background on winning cells
       */
      this.markWinningCells = function(){
         if(!this.winningCells) return;
         for(var i = 0; i < this.winningCells.length; i++){
            this.gameCells[this.winningCells[i]].style.backgroundColor = cellbackWin;
         }
      }

      /**
       * Flag to indicate a winner was found
       */
      this.hasWinner = false;

      /**
       * Identify the cells in the winning line
       */
      this.winningCells = null;

      /**
       * Last person to win - player or computer
       */
      this.lastWinner = null;
      
      /**
        * The player who is currently allowed to make a move
        */
       this.currentPlayer = TTT.Players.Human;
      
      /**
       * The ID of your opponent
       */
      this.opponentId = null;
      
      function init(){
         me.displayBoardElem = document.getElementById("gameboard");
         me.gameCells = me.displayBoardElem.getElementsByTagName("td");
         me.moves = new Array(9);
         me.messageBlock = document.getElementById("messages");
         me.clear();
      }

      init();
   }
};

/**
 * Game object method defintions
 */
TTT.Game.prototype = {

   writeMessage: function(message, color){
       if(color){
           this.messageBlock.innerHTML += "<span style='color:" + color + ";'>" + message + "</span>";
       }
       else{
           this.messageBlock.innerHTML += message;
       }
   },

   /**
    * Makes a move and records the result.
    * Draws the move on the game board
    * @param {Object} player
    * @param {Object} position
    */
   makeMove : function(player, position){
       if(player !== this.currentPlayer) return;
       
       this.lookForWin();
       if(!this.hasWinner){
           if(!this.moves[position]){
               this.moves[position] = player;
               this._drawMove(player, position);
               this.lookForWin();
           }
           else{
               writeMessage("Invalid Move for " + player, "red");
           }
           
           this.currentPlayer = (player === TTT.Players.Human) ? TTT.Players.Computer : TTT.Players.Human;
       }
       if(this.hasWinner){
           this.markWinningCells();
           
           var this_won = (player === TTT.Players.Human) ? true: false;
           TTT.Record.Poster.post(this_won);
       }
   },
   /**
    * Draws the player's mark in the cell
    * @param {Object} player
    * @param {Object} position
    */
   _drawMove: function(player, position){
       this.gameCells[position].innerHTML = player;
   },

   /**
    * Intense AI to compete in most difficult tick-tack-toe tournaments
    */
   makeComputerMove : function(){
       var die = 50;
       var pos;
       var found = false;
       var i=0;
       while(!found && i++ < die){
           pos = new Date().getMilliseconds() % 10;
           if(pos == 9) pos = 8;
           found = (!this.moves[pos]);
       }
       if(!found){
           for(i=0; i < 9; i++){
               if(!this.moves[i]){
                   this.makeMove(TTT.Players.Computer, i);
                   return;
               }
           }
           alert('no move');
           return;
       }
       else{
           this.makeMove(TTT.Players.Computer, pos);
       }
   },


   lookForWin: function(){
       //horizontal
       var i=0;
       for(i=0; i<9; i=i+3){
           this.hasWinner = this.matchMovePositions(i,i+1,i+2);
           if(this.hasWinner){
               this.winningCells = [i,i+1,i+2]
               return;
           }
       }
       
       //vertical
       for(i=0; i<3; i++){
           this.hasWinner = this.matchMovePositions(i,i+3,i+6);
           if(this.hasWinner){
               this.winningCells = [i,i+3,i+6]
               return;
           }
       }
       
       //diag
       if(!this.hasWinner){
           this.hasWinner = this.matchMovePositions(0,4,8);
           if(this.hasWinner){
               this.winningCells = [0,4,8]
           }
       }
       if(!this.hasWinner){
           this.hasWinner = this.matchMovePositions(2,4,6);
           if(this.hasWinner){
               this.winningCells = [2,4,6]
           }
       }

   },

   /**
    * Tests three positions to see if they match
    * @param {Object} a
    * @param {Object} b
    * @param {Object} c
    */
   matchMovePositions : function(a, b, c){
       if(this.moves[a]){
           return (this.moves[a] == this.moves[b] && this.moves[a] == this.moves[c]);
       }
       return false;
   }
};

TTT.CustomBackground = function(){
   this._hasCustomBG = false;
   this.photo = {};
   this.cellbackCustomBG = "";
   
   /**
    * Returns true/false based on if a custom user background is 
    * currently in use
    */
   this.usingCustomBG = function(){
      return this._hasCustomBG;
   };
   
   /**
    * Gets the background of the TTT board
    */
   this.getCustomBG = function(){
      var start = currentGame.displayBoardElem.style.background.indexOf("http");
      var end = currentGame.displayBoardElem.style.background.indexOf(")");
      
      return currentGame.displayBoardElem.style.background.substring(start, end);
   };
   
   /**
    * Sets the background of the TTT board to a custom user image
    */
   this.setCustomBG = function(photo){
      this.photo = photo;
      var img_src = photo.getField(MyOpenSpace.Photo.Field.IMAGE_URI);
      
      currentGame.displayBoardElem.style.background = "url(" + img_src + ")";
      this._hasCustomBG = true;
      
      for(i = 0; i < currentGame.gameCells.length; i++){
         currentGame.gameCells[i].style.backgroundColor = this.cellbackCustomBG;
      }
   };
}

TTT.LightBox = {
   _overlay:null,
   _light_box:null,
   _light_box_container:null,
   _is_init:false,
   
   _init:function(){
      this._overlay = document.getElementById("overlay");
      this._light_box = document.getElementById("light_box");
      this._light_box_container = document.getElementById("light_box_container");
      this._is_init = true;
   },
   
   show:function(){
      if(!this._is_init){
         this._init();
      }
      
      this._overlay.style.display = "block";
      this._light_box_container.style.display = "block";
   },
   hide:function(){
      this._overlay.style.display = "none";
      this._light_box_container.style.display = "none";
   },
   setContent:function(html){
      if(!this._is_init){
         this._init();
      }
      
      this._light_box.innerHTML = html;
   }
};

TTT.List = function(list_type, id_key, name_key, image_key, class_name, item_onclick){
   this.list_type = list_type;
   this.list = [];
   this.list_dom = {};
   this.first = 1;
   this.max = 20;
   this.total = 0;
   this.retries = 3;
   
   this.id_key = id_key;
   this.name_key = name_key;
   this.image_key = image_key;
   this.class_name = class_name;
   this.item_onclick = item_onclick;
};

TTT.ListTypes = {
   ALL_FRIENDS:"ALL_FRIENDS",
   HASAPP_FRIENDS:"HASAPP_FRIENDS",
   SET_BACKGROUND:"SET_BACKGROUND"
};

TTT.Lists = {
   _current:"",
   
   itemClicked:[],
   
   getCurrentList:function(){
      for(var key in this.lists){
         if(this.lists[key].list_type === this._current){
            return this.lists[key];
         }
      }
   },
   
   setCurrentList:function(list_type){
      this._current = list_type;
   },
   
   lists:{
      all_friends:new TTT.List(TTT.ListTypes.ALL_FRIENDS, opensocial.Person.Field.ID, opensocial.Person.Field.NICKNAME, opensocial.Person.Field.THUMBNAIL_URL, "friend", function(){})
   },
   
   markup_format:"<div><img src='{0}' /></div>{1}",
   
   permCallback:function(response){
      if(!response.hadError()){
         TTT.Lists.retryRequest();
      }
   },
   
   retryRequest:function(){
      TTT.Lists.getCurrentList().retries--;
      window.setTimeout(TTT.Tabs.getCurrentTab().action, 250);
   }
};

var currentGame = null;

function makePlayerMove(e){
   if(!e) var e = window.event;

   var cell = (e.target) ? e.target.getAttribute("gamecell") : e.srcElement.getAttribute("gamecell");
   currentGame.makeMove(TTT.Players.Human, cell);
   if(!currentGame.hasWinner){
       window.setTimeout(function(){
           currentGame.makeComputerMove();
       }, 500);
   }

}

/**
 * Function called by the onload handler and the entry point for the app
 */
function initializeGame(){
   if(currentGame){
      currentGame.clear();
   }
   else{
      gadgets.window.adjustHeight(3000);
      currentGame = new TTT.Game();
   }
}


var retries = 3;
var debug = true;
var viewer = {{ viewer_obj }};

/**
 * Output the viewer data onto the surface
 */
function printPerson(div){
   if(!viewer || !viewer.fullprofile){
      log("Oops, there was an error, try refreshing the page!");
   }
   else{
      var base_obj = [], num_set = 0;
      for(var i = 0; i < div.childNodes.length; i++){
         if(1 === div.childNodes[i].nodeType){
            base_obj[num_set] = div.childNodes[i];
            if(1 === num_set){
               break;
            }
            else{
               num_set++;
            }
         }
      }
      
      var img_div = base_obj[0].firstChild.firstChild;
      var name_div = base_obj[1].firstChild;
      var location_div = base_obj[1].childNodes[1];
      var gender_div = base_obj[1].childNodes[2];
   
      // you can set the src attribute of an <img> 
      // tag directly with THUMBNAIL_URL
      img_div.src = viewer.fullprofile.basicprofile.image;
      
      // getDisplayName is a shortcut for 
      // getField(opensocial.Person.Field.NICKNAME)
      name_div.innerHTML = viewer.fullprofile.basicprofile.name;
      
      // get the viewer's status
      var status = viewer.status;
      if(status && status.length > 0){
      
         // if the status has been set append it after the name
         name_div.innerHTML += " \"" + status + "\"";
      }
   
      // get the viewer's mood
      var mood = viewer.mood;
      if(mood && mood.length > 0){
      
         // if the mood has been set append it after the status
         name_div.innerHTML += " \"" + mood + "\"";
      }
      
      // the Address object is used similarly to the Person object, 
      // both pass a Field into a getField function
      location_div.innerHTML = viewer.fullprofile.region;
      
      // getDisplayValue is defined by the specific container and can and
      // will differ between containers and is designed for displaying only
      gender_div.innerHTML = viewer.fullprofile.gender;
      
      // the response of getKey is defined by OpenSocial and therefore
      // you can compare the result to some known value
      if(viewer.fullprofile.gender.toLowerCase() === "female"){
         div.style.backgroundColor = "#fcf";
      }
      else{
         div.style.backgroundColor = "#09f";
      }
      
      // MySpace provides a built in StringBuilder class 
      // which can take an initial string in the constructor,
      // and has append and toString functions, this can be 
      // easier to use in some cases than simple concatenation
      var sb = new MyOpenSpace.StringBuilder("<div id='player_bio'>");
      sb.append("<div id='player_bio_title'>Player Bio</div>");
      sb.append("<div style='margin:5px;'>");
      sb.append("<div class='left' style='height:300px;'>");
      sb.append("<img style='width:200px;' class='profile_image' src='");
      
      sb.append(viewer.fullprofile.basicprofile.largeImage);
      sb.append("' /></div><div>");
      
      if("" !== status){
         sb.append("<b>");
         sb.append(status);
         sb.append("</b><br>");
      }
      
      sb.append(viewer.fullprofile.basicprofile.name + "<br>");
      sb.append(viewer.fullprofile.basicprofile.userId  + "<br>");
      sb.append(viewer.fullprofile.age + "<br>");
      sb.append(viewer.fullprofile.city + " ");
      sb.append(viewer.fullprofile.region + " ");
      sb.append(viewer.fullprofile.country + " ");
      sb.append(viewer.fullprofile.postalcode  + "<br>");
      sb.append(viewer.fullprofile.culture  + "<br>");
      sb.append(viewer.fullprofile.hometown  + "<br>");
      sb.append(viewer.fullprofile.maritalstatus  + "<br>");
      sb.append(viewer.fullprofile.aboutme  + "<br>");
      sb.append(viewer.books  + "<br>");
      sb.append(viewer.desiretomeet  + "<br>");
      sb.append(viewer.headline  + "<br>");
      sb.append(viewer.heroes  + "<br>");
      sb.append(viewer.interests  + "<br>");
      sb.append(viewer.movies  + "<br>");
      sb.append(viewer.music  + "<br>");     
      sb.append(viewer.occupation  + "<br>");      
      sb.append(viewer.television  + "<br>");
      sb.append(viewer.zodiacsign  + "<br>");
      
      sb.append("</div></div><div class='clear'></div>");
      sb.append("<div id='bio_close'>");
      sb.append("<a href='javascript:TTT.LightBox.hide();'>close...</a>");
      sb.append("</div></div>");

      TTT.LightBox.setContent(sb.toString());
   }
}

function openProfile(){
   // profile URL is a simple string that can go directly into the src
   // attribute of an <img> tag, or, like here, directly into window.open()
   window.open(viewer.basicprofile.webUri);
}

/**
 * Output an error message if debug mode is enabled
 * @param {String} message
 */
function log(message){
   var errFeed = document.getElementById("messages");
   if(errFeed){
      errFeed.innerHTML += message + "<br />";
   }
}

function runOnLoad(){
   initializeGame();
   printPerson(document.getElementById("myinfo"));
}

</script>
</head>

<body onload="runOnLoad()">
	<div id="overlay"></div>
	<div id="light_box_container"><div id="light_box"></div></div>
	
	<div class="container">
	   <h1>OpenSocial Tic-Tac-Toe</h1>
	   
	   <div>
	      <div class="left tab_spacer small_width">&nbsp;</div>
	      <div id="tab0" class="left tab tab_selected">Play</div>
	      <a id="tab1" class="left tab tab_last" href="/invite?opensocial_viewer_id={{ viewer_id }}&appid={{ appid }}&opensocial_token={{ opensocial_token }}">Invite</a>
	      <div class="left tab_spacer large_width">&nbsp;</div>
	      <div class="clear"></div>
	   </div>
	</div>
	
	<div id="play_container" class="container">
	   <div class="left">
	       <table id="gameboard" onclick="makePlayerMove(event)">
	
	           <tr>
	               <td gamecell="0"></td>
	               <td gamecell="1"></td>
	               <td gamecell="2"></td>
	           </tr>
	           <tr>
	               <td gamecell="3"></td>
	               <td gamecell="4"></td>
	               <td gamecell="5"></td>
	
	           </tr>
	           <tr>
	               <td gamecell="6"></td>
	               <td gamecell="7"></td>
	               <td gamecell="8"></td>
	           </tr>
	       </table>
	   </div>
	
	   <div id="right_column">
	      <div id="myinfo" class="player_info right_column">
	         <div class="left"><a href="javascript:openProfile();"><img class="profile_image" src="http://x.myspacecdn.com/images/no_pic.gif" /></a><div class="record" id="myrecord"></div></div>
	         <div><div></div><div></div><div></div><div class="more"><a href="javascript:TTT.LightBox.show();">More...</a></div></div>
	         <div class="clear"></div>
	      </div>
	      
	      <div id="opponentinfo" class="player_info right_column hide">
	         <div class="left"><a href="javascript:openProfile();"><img class="profile_image" src="http://x.myspacecdn.com/images/no_pic.gif" /></a><div class="record" id="mopponentrecord"></div></div>
	         <div><div></div><div></div><div></div><div class="more"><a href="javascript:TTT.LightBox.show();">More...</a></div></div>
	         <div class="clear"></div>
	      </div>
	      
	      <div class="clear"></div>
	   
	      <div id="game_list" class="right_column hide"></div>
	   </div>
	
	   <div class="clear"></div>
	
	   <button onclick="initializeGame();">New Game</button>&nbsp;
	
	</div>
	
	<div id="invite_container" class="container hide"><div><button onclick="rsmBulletin();">Send a Bulletin!</button>&nbsp;<button onclick="rsaInviteButtonClicked();">Send Invite(s)</button></div></div>
	
	<div id="messages"></div>
	
	<style>
	   img
	   {
	      border:0;
	   }
	   body
	   {
	      margin:0;
	      padding:0;
	      font-family:Verdana;
	      font-size:12pt;
	   }
	   
	   #gameboard
	   {
          margin:10px;
	      border-collapse: collapse;
	      border:2px solid black;
	      padding:5px;
	      margin-bottom:5px;
	      empty-cells:show;
	      font-size: 40pt;
	      font-family:Verdana;
	      font-weight:bold;
	      color:#fff;
	      cursor:pointer;
	   }
	   #gameboard td
	   {
	      color:#fff;
	      border:1px solid white;
	      text-align:center;
	      width:120px;
	      height:120px;
	   }
	   .container
	   {
	   	  margin:10px;
	   }
	   .tab
	   {
	      border:solid 1px black;
	      border-right:0;
	      padding:5px 5px 4px;
	      cursor:pointer;
	      background-color:#ddd;
		  color:black;
		  text-decoration:none;
	   }
	   .tab_last
	   {
	      border-right:solid 1px black;
	   }
	   .tab_spacer
	   {
	      border-bottom:solid 1px black;
	      padding:5px;
	   }
	   .small_width
	   {
	      width:40px;
	   }
	   .large_width
	   {
	      width:50%;
	   }
	   .tab_selected
	   {
	      border-bottom:0;
	      background-color:white;
	   }
	   .friend
	   {
	      border:solid 1px black;
	      margin:5px;
	      padding:5px;
	      float:left;
	      width:90px;_width:102px;
	      overflow:hidden;
	      text-align:center;
	      height:160px;
	      cursor:pointer;
	   }
	   .photo
	   {
	      border:solid 1px black;
	      margin:5px;
	      padding:5px;
	      float:left;
	      width:130px;_width:142px;
	      overflow:hidden;
	      text-align:center;
	      height:130px;_height:142px;
	      cursor:pointer;
	   }
	   .photo img
	   {
	      width:130px;
	      height:110px;
	   }
	   .pager
	   {
	      font-size:9pt;
	   }
	   .pager span
	   {
	      color:blue;
	      cursor:pointer;
	   }
	   #messages
	   {
	      height:20px;
	      overflow:auto;
	      color:Red;
	   }
	   #right_column
	   {
	      float:right;
	      width:500px;
	   }
	   .right_column
	   {
	      float:right;
	      margin:5px;
	      width:100%;
	   }
	   .player_info
	   {
	      border:solid 2px black;
	      padding:5px;
	   }
	   .profile_image
	   {
	      margin:5px;
	      border:solid 1px black;
	   }
	   .more a
	   {
	      line-height:40px;
	      padding:5px;
	      border:solid 1px black;
	      cursor:pointer;
	      text-decoration:none;
	      color:Black;
	      background-color:White;
	   }
	   #overlay
	   {
	   	display:none;
	   	width:100%;
	   	height:100%;
	   	background-color:Black;
	   	left:0;
	   	top:0;
	   	z-index:100000;
	   	position:absolute;
	   	opacity:0.6;
	   	filter: alpha(opacity=60);
	   }
	   #light_box_container
	   {
	   	width:100%;
	   	left:0;
	   	position:absolute;
	   	top:70px;
	   	z-index:100001;
	   	text-align:center;
	   	display:none;
	   }
	   #light_box
	   {
	   	margin:auto;
	   	width:650px;
	   	background-color:White;
	   	border:solid 4px black;
	   	text-align:left;
	   }
	   #player_bio
	   {
	   	margin:5px;
	   }
	   #player_bio_title
	   {
	   	border-bottom:solid 1px black;
	   	font-weight:bold;
	   	padding:1px 0 5px 0;
	   	text-align:center;
	   }
	   #bio_close
	   {
	   	border-top:solid 1px black;
	   	margin-top:5px;
	   	padding:3px;
	   	text-align:center;
	   }
	   #bio_close a
	   {
	   	text-decoration:none;
	   }
	   .clear
	   {
	      clear:both;
	   }
	   .left
	   {
	      float:left;
	   }
	   .right
	   {
	      float:right;
	   }
	   .hide
	   {
	      display:none;
	   }
	   .record
	   {
	      font-size:12px;
	      text-align:center;
	   }
	</style>

</body></html>